<script lang="ts" setup>
import type { Editor } from "@/tiptap";
import { Dropdown as VDropdown, vTooltip } from "floating-vue";
import { ref, type Component } from "vue";

const props = withDefaults(
  defineProps<{
    editor: Editor;
    isActive?: ({ editor }: { editor: Editor }) => boolean;
    visible?: ({ editor }: { editor: Editor }) => boolean;
    icon?: Component;
    iconStyle?: string;
    title?: string;
    action?: ({ editor }: { editor: Editor }) => Component | boolean | void;
  }>(),
  {
    isActive: () => false,
    visible: () => true,
    title: undefined,
    action: undefined,
    icon: undefined,
    iconStyle: undefined,
  }
);

const componentRef = ref<Component | void | undefined>();

const handleBubbleItemClick = (editor: Editor) => {
  if (!props.action) {
    return;
  }
  const callback = props.action?.({ editor });
  if (typeof callback === "object") {
    componentRef.value = callback;
  }
};

const handleHide = () => {
  componentRef.value = undefined;
};
</script>

<template>
  <VDropdown class="bubble-item-dropdown" :triggers="[]" :auto-hide="true" :shown="!!componentRef" :distance="10"
    @hide="handleHide">
    <button v-if="visible({ editor })" v-tooltip="{
      content: title,
      distance: 8,
      delay: {
        show: 0,
      },
    }" :class="{ 'is-active': isActive({ editor }) }" :title="title" class="bubble-item-button"
      @click="handleBubbleItemClick(editor)">
      <component :is="icon" :style="iconStyle" class="bubble-item-icon" />
    </button>
    <template #popper>
      <div class="bubble-item-popper">
        <KeepAlive>
          <component :is="componentRef" v-bind="props"></component>
        </KeepAlive>
      </div>
    </template>
  </VDropdown>
</template>

<style lang="scss" scoped>
.bubble-item-dropdown {
  display: inline-flex;
}

.bubble-item-button {
  border-radius: 0.375rem; // rounded-md
  padding: 0.5rem; // p-2
  font-size: 1.125rem; // text-lg
  color: var(--editor-button-text);
  border: none;
  background-color: transparent;
  cursor: pointer;
  transition: background-color 0.15s ease;
  display: inline-flex;
  align-items: center;
  justify-content: center;

  &:hover {
    background-color: var(--editor-button-hover-bg);
  }

  &.is-active {
    background-color: var(--editor-button-active-bg) !important;
    color: var(--editor-button-text-active) !important;
  }
}

.bubble-item-icon {
  height: 1.25rem; // h-5
  width: 1.25rem; // w-5
}

.bubble-item-popper {
  position: relative;
  max-height: 18rem; // max-h-72
  width: 24rem; // w-96
  overflow: hidden;
  overflow-y: auto;
  border-radius: 0.375rem; // rounded-md
  background-color: var(--editor-toolbar-bg);
  padding: 0.25rem; // p-1
  box-shadow: var(--editor-box-shadow-light);
}
</style>

<style lang="scss">
.v-popper__popper.v-popper__popper--show-from .v-popper__wrapper {
  transform: scale(0.9);
}

.v-popper__popper.v-popper__popper--show-to .v-popper__wrapper {
  transform: none;
  transition: transform 0.1s;
}
</style>
